# -*- coding: utf-8 -*-
import json

import requests
from django.forms import model_to_dict
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt

from utils.tencent.cos import delete_file, delete_file_list, credential
from web import models
from web.forms.file import FolderModelForm, FileModelForm


def file(request, project_id):
    """
    文件
    http://127.0.0.1:8000/manage/5/file/
    http://127.0.0.1:8000/manage/5/file?folder=1
    """
    parent_obj = None
    folder_id = request.GET.get('folder', '')
    # 处理父级folder
    if folder_id.isdecimal():
        parent_obj = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                          project=request.tracer.project).first()
    
    if request.method == 'GET':
        
        # 导航条
        breadcrumb_list = []
        parent = parent_obj
        while parent:
            # breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            breadcrumb_list.insert(0, model_to_dict(parent, ['id', 'name']))
            parent = parent.parent
        
        # 获取当前目录下的所有文件和文件夹
        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        
        if parent_obj:
            file_list = queryset.filter(parent=parent_obj).order_by('-file_type')
        else:
            file_list = queryset.filter(parent__isnull=True).order_by('-file_type')
        
        form = FolderModelForm(request, parent_obj)
        return render(request, 'file.html', {'form': form, 'file_list': file_list, 'breadcrumb_list': breadcrumb_list, 'folder_obj': parent_obj})
    
    # 创建文件夹 & 修改文件夹
    fid = request.POST.get('fid', '')
    obj = None
    if fid.isdecimal():
        # 修改
        obj = models.FileRepository.objects.filter(id=int(fid), file_type=2, project=request.tracer.project).first()
    
    if obj:
        form = FolderModelForm(request, parent_obj, data=request.POST, instance=obj)
    else:
        form = FolderModelForm(request, parent_obj, data=request.POST)
    
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_obj
        form.save()
        
        return JsonResponse({'status': True})
    
    return JsonResponse({'status': False, 'error': form.errors})


def file_delete(request, project_id):
    """删除文件"""
    fid = request.GET.get('fid')
    # 级联删除
    del_obj = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    
    if del_obj.file_type == 1:
        # 删除文件
        pass
        # 删除文件，调整容量空间
        request.tracer.project.use_space -= del_obj.file_size
        request.tracer.project.save()
        
        # cos删除文件
        delete_file(request.tracer.project.bucket, request.tracer.project.region, del_obj.key)
        
        # 删除db的
        del_obj.delete()
        
        return JsonResponse({'status': True})
    
    """
    删除文件夹
    找到该文件夹下所有的文件夹和文件夹，
    """
    total_size = 0
    key_list = []
    
    folder_list = [del_obj, ]
    for folder in folder_list:
        child_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                          parent=folder).order_by('-file_type')
        for child in child_list:
            if child == 2:
                folder_list.append(child)
            else:
                # 计算被删除文件的大小
                total_size += child.file_size
                # 构造数据
                key_list.append({'Key': child.key})
    
    # cos 删除文件
    if key_list:
        delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)
    
    if total_size:
        # 调整容量空间
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()
    # 删除文件
    del_obj.delete()
    
    return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    """获取临时凭证"""
    
    # 把M转成B
    per_file_limit = request.tracer.price_policy.project_file_size * 1024 * 1024
    total_file_limit = request.tracer.price_policy.project_space * 1024 * 1024 * 1024
    
    total_size = 0
    # 获取文件及大小
    file_list = json.loads(request.body.decode('utf-8'))
    for item in file_list:
        # 文件字节大小 B
        msg = '单文件超出限制(最大{}M)，文件：{}，请升级套餐'.format(request.tracer.price_policy.project_file_size, item['name'])
        
        # 单文件限制
        if item['size'] > per_file_limit:
            return JsonResponse({'status': False, 'error': msg})
        total_size += item['size']
    
    # 总容量限制
    # request.tracer.price_policy.project_space 项目空间
    # request.tracer.project.use_space 用户空间
    if request.tracer.project.use_space + total_size > per_file_limit:
        return JsonResponse({'status': False, 'error': '容量超出限制，请升级套餐'})
    
    data = credential(request.tracer.project.bucket, request.tracer.project.region)

    return JsonResponse({'status': True, 'data': data})


@csrf_exempt
def file_post(request, project_id):
    """文件成功上传cos后，将信息写入数据库"""
    
    form = FileModelForm(request, data=request.POST)
    if form.is_valid():
        
        # 验证通过 写入数据库
        # form.instance.file_type = 1
        # form.update_user = request.tracer.user
        # 通过ModelForm.save储存到数据库的中的数据返回的instance对象，无法通过get_xxx_display获取choice的中文信息
        # form.save()
        data_dict = form.cleaned_data
        data_dict.pop('etag')
        data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
        
        instance = models.FileRepository.objects.create(**data_dict)
        
        # 更新项目已使用空间
        request.tracer.project.use_space += data_dict.get('file_size')
        request.tracer.project.save()
        
        result = {
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.name,
            'datetime': instance.update_time,
            'download_url': reverse('web:file_download', kwargs={'project_id': project_id, 'file_id': instance.id}),
            # 'file_type': instance.get_file_type_display(),
        }
        
        return JsonResponse({'status': True, 'data': result})
        
    return JsonResponse({'status': False, 'data': '文件错误'})


def file_download(request, project_id, file_id):
    """文件下载"""
    
    obj = models.FileRepository.objects.filter(id=file_id, project_id=project_id).first()
    
    data = requests.get(obj.file_path).content

    response = HttpResponse(data)
    # 设置响应头
    response['content-Disposition'] = "attachment; filename={}".format(obj.name)
    return response
